package vip.aster.workflow.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import vip.aster.common.utils.PageInfo;
import vip.aster.workflow.constant.WorkFlowConstant;
import vip.aster.workflow.dto.BatchAddColumnDto;
import vip.aster.workflow.dto.FormItem;
import vip.aster.workflow.entity.WfForm;
import vip.aster.workflow.mapper.WfFormMapper;
import vip.aster.workflow.query.WfFormQuery;
import vip.aster.workflow.service.DataSourceService;
import vip.aster.workflow.service.WfFormService;
import vip.aster.workflow.utils.DbUtil;
import vip.aster.workflow.vo.WfFormVO;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 流程表单 服务实现类
 * </P>
 *
 * @author Aster lipian1004@163.com
 * @since 2024-04-15 14:28:44
 */
@Slf4j
@Service
@AllArgsConstructor
public class WfFormServiceImpl extends ServiceImpl<WfFormMapper, WfForm> implements WfFormService {

    /**
     * 流程设计Mapper
     */
    private WfFormMapper wfFormMapper;

    /**
     * 数据源service
     */
    private DataSourceService dataSourceMapper;

    /**
     * 分页
     *
     * @param query 查询条件
     * @return 查询结果
     */
    @Override
    public PageInfo<WfFormVO> pageList(WfFormQuery query) {
        Page<WfForm> page = new Page<>(query.getPageNum(), query.getPageSize());
        IPage<WfForm> wfFormPage = wfFormMapper.selectWfFormPage(page, query);
        return new PageInfo<>(WfFormVO.convertList(wfFormPage.getRecords()), wfFormPage.getTotal());
    }

    /**
     * 查询表单集合
     *
     * @param query 查询条件
     * @return 表单集合
     */
    @Override
    public List<WfFormVO> list(WfFormQuery query) {
        List<WfForm> list = wfFormMapper.selectWfFormPage(query);
        return WfFormVO.convertList(list);
    }

    /**
     * 保存
     *
     * @param vo 流程表单
     */
    @Override
    public void save(WfFormVO vo) {
        WfForm entity = vo.reconvert();
        // 通过firmID查询当前表单版本号
        if (!StringUtils.isBlank(vo.getCode())) {
            entity.setVersion(this.selectMaxVersion(vo.getCode()) + 1);
        } else {
            entity.setCode(WorkFlowConstant.FLOW_FORM_ID_KEY + IdUtil.getSnowflakeNextId());
            entity.setVersion(1);
        }
        if (StrUtil.isNotBlank(entity.getId())) {
            wfFormMapper.updateById(entity);
        } else {
            wfFormMapper.insert(entity);
        }
    }

    /**
     * 处理列信息
     *
     * @param entity   当前表单实体
     * @param wfFormVO 最新表单VO
     */
    @Override
    public void handleField(WfForm entity, WfFormVO wfFormVO) {
        // 新增列
        List<FormItem> addFieldList = new ArrayList<>();
        // 修改列
        List<FormItem> updateFieldList = new ArrayList<>();
        // 获取旧表单ID字段
        List<String> oldFieldList = new ArrayList<>();
        // 获取旧表单字段
        JSONArray oldFormItems = wfFormVO.getFormItems();
        if (!CollectionUtils.isEmpty(oldFormItems)) {
            for (int i = 0; i < oldFormItems.size(); i++) {
                oldFieldList.add(oldFormItems.getJSONObject(i).getString("id"));
            }
        }
        // 获取新表单字段
        String newFieldItem = entity.getFormItems();
        List<FormItem> newFieldList = JSONArray.parseArray(newFieldItem, FormItem.class);
        // 判断获取需要新增的字段
        for (FormItem formField : newFieldList) {
            // 不包含旧表单ID就是新增的列, 其他都是修改的
            if (!oldFieldList.contains(formField.getId())) {
                addFieldList.add(formField);
            } else {
                updateFieldList.add(formField);
            }
        }
        // 发送新增列sql和修改列sql
        BatchAddColumnDto batchAddColumnDto = new BatchAddColumnDto();
        batchAddColumnDto.setTableName(entity.getCode());
        if (!CollectionUtils.isEmpty(addFieldList)) {
            batchAddColumnDto.setSql(DbUtil.createColumn(addFieldList));
            dataSourceMapper.batchAddColumnList(batchAddColumnDto);
        }
        if (!CollectionUtils.isEmpty(updateFieldList)) {
            batchAddColumnDto.setSql(DbUtil.createColumn(updateFieldList));
            dataSourceMapper.batchUpdateColumn(batchAddColumnDto);
        }
    }

    /**
     * 获取最后一个版本的表单
     *
     * @param code code
     * @return 最后一个版本的表单
     */
    @Override
    public WfFormVO getLastByFormCode(String code) {
        List<WfForm> list = wfFormMapper.selectWfFormPage(new WfFormQuery().setCode(code));
        if (!CollectionUtils.isEmpty(list)) {
            WfForm wfForm = list.get(0);
            return new WfFormVO(wfForm);
        }
        return null;
    }

    /**
     * 通过主键查询表单项
     *
     * @param id 主键
     * @return 表单项
     */
    @Override
    public List<FormItem> getFormItemsById(String id) {
        WfForm wfForm = this.getById(id);
        if (wfForm == null || StringUtils.isBlank(wfForm.getFormItems())) {
            return new ArrayList<FormItem>();
        }
        return JSONArray.parseArray(wfForm.getFormItems(), FormItem.class);
    }

    /**
     * 通过表单编码查询最新版本的表单信息
     * @param code 表单编码
     * @return 最新版本的表单信息
     */
    @Override
    public WfForm getLastFormInfo(String code) {
        List<WfForm> list =  wfFormMapper.getLastFormInfo(code);
        if (CollUtil.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 查询最大版本号
     *
     * @param code 表单编码
     * @return 最大版本号
     */
    @Override
    public Integer selectMaxVersion(String code) {
        if (StringUtils.isBlank(code)) {
            return 0;
        }
        Integer version = wfFormMapper.selectMaxVersion(code);
        return version == null ? 0 : version;
    }

    /**
     * 流程表单删除
     *
     * @param idList 主键集合
     */
    @Override
    public boolean wfFormDelete(List<String> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return true;
        }
        List<WfForm> wfForms = this.listByIds(idList);
        if (CollectionUtils.isEmpty(wfForms)) {
            return true;
        }
        List<String> formCodes = wfForms.stream().map(WfForm::getCode).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(formCodes)) {
            return true;
        }
        LambdaQueryWrapper<WfForm> wrapper = getWrapper(new WfFormQuery());
        wrapper.in(WfForm::getCode, formCodes);
        return this.remove(wrapper);
    }

    /**
     * 获取查询条件
     *
     * @param query 查询实体
     * @return 返回LambdaQueryWrapper
     */
    private LambdaQueryWrapper<WfForm> getWrapper(WfFormQuery query) {
        LambdaQueryWrapper<WfForm> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StrUtil.isNotBlank(query.getFormName()), WfForm::getFormName, query.getFormName());
        wrapper.eq(StrUtil.isNotBlank(query.getCode()), WfForm::getCode, query.getCode());
        wrapper.eq(StrUtil.isNotBlank(query.getStatus()), WfForm::getStatus, query.getStatus());
        wrapper.eq(StrUtil.isNotBlank(query.getAppId()), WfForm::getAppId, query.getAppId());
        wrapper.eq(StrUtil.isNotBlank(query.getProcessDefId()), WfForm::getProcessDefId, query.getProcessDefId());
        return wrapper;
    }

}
